package cz.matasek.dbLogger.gui;

import cz.matasek.dbLogger.Label;
import cz.matasek.dbLogger.model.Database;
import cz.matasek.dbLogger.model.Table;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

/**
 * The panel contains list of tables which exist in the database.
 *
 * @author Luboš Matásek
 */
public class TablesPanel extends javax.swing.JPanel implements Refreshable {

    /**
     * Serial version UID.
     */
    private static final long serialVersionUID = 7532701069269510570L;
    /**
     * The database object.
     */
    private Database database;
    /**
     * Mapping of tables to their info panels.
     */
    private Map<Table, TableInfoPanel> tableInfoPanels;

    /** 
     * Creates a new <code>TablesPanel</code>.
     *
     * @param database the database
     */
    public TablesPanel(Database database) {
        this.database = database;

        initComponents();

        refresh();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        _tables = new javax.swing.JTree();
        _tableInfo = new javax.swing.JPanel();

        setMinimumSize(new java.awt.Dimension(595, 372));
        setPreferredSize(new java.awt.Dimension(595, 372));

        jSplitPane1.setBorder(null);
        jSplitPane1.setDividerSize(3);
        jSplitPane1.setMinimumSize(new java.awt.Dimension(575, 350));
        jSplitPane1.setPreferredSize(new java.awt.Dimension(575, 350));

        jScrollPane1.setBorder(null);
        jScrollPane1.setMinimumSize(new java.awt.Dimension(175, 350));
        jScrollPane1.setPreferredSize(new java.awt.Dimension(175, 350));

        _tables.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        _tables.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root");
        _tables.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
        _tables.setMaximumSize(new java.awt.Dimension(32767, 32767));
        _tables.setMinimumSize(new java.awt.Dimension(175, 350));
        _tables.setPreferredSize(new java.awt.Dimension(175, 350));
        _tables.setRowHeight(20);
        _tables.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                _tablesValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(_tables);

        jSplitPane1.setLeftComponent(jScrollPane1);

        _tableInfo.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
        _tableInfo.setPreferredSize(new java.awt.Dimension(400, 350));
        _tableInfo.setLayout(new java.awt.GridLayout(1, 1));
        jSplitPane1.setRightComponent(_tableInfo);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 575, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 350, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Fired when any object in the tree is selected.
     * 
     * @param evt tree selection event
     */
    private void _tablesValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event__tablesValueChanged
        DefaultMutableTreeNode node =
                (DefaultMutableTreeNode) _tables.getLastSelectedPathComponent();

        if (node != null && node.isRoot()) {
            _tableInfo.removeAll();
            setTablePanelTitle(null);
        } else if (node != null) {
            _tableInfo.removeAll();
            setTablePanelTitle(node.getUserObject().toString());
            _tableInfo.add(tableInfoPanels.get(node.getUserObject()));
        }

        Gui.getInstance().repaint();
}//GEN-LAST:event__tablesValueChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel _tableInfo;
    private javax.swing.JTree _tables;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSplitPane jSplitPane1;
    // End of variables declaration//GEN-END:variables

    /**
     * Sets the title of this panel.
     *
     * @param title title of the panel
     */
    public void setTablePanelTitle(String title) {
        TitledBorder border = (TitledBorder) _tableInfo.getBorder();
        if (title == null) {
            border.setTitle("");
        } else {
            border.setTitle(Label.TABLE + " " + title);
        }
    }

    /**
     * Returns tree model containing all tables in the database.
     *
     * @return tree model of all tables in the database
     */
    public final DefaultTreeModel getTablesTreeModel() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(Label.TABLES);

        List<Table> tables = new ArrayList<Table>(database.getNonLoggingTables());
        Collections.sort(tables);
        for (Table table : tables) {
            root.add(new DefaultMutableTreeNode(table));
        }

        return new DefaultTreeModel(root);
    }

    /**
     * Returns table info panel for every table in the database.
     *
     * @return mapping of table names to their info panels
     */
    public final Map<Table, TableInfoPanel> createTableInfoPanels() {
        Map<Table, TableInfoPanel> infoPanels =
                new HashMap<Table, TableInfoPanel>();

        for (Table table : database.getNonLoggingTables()) {
            TableInfoPanel tableInfoPanel =
                    new TableInfoPanel(table.getName(), database);
            infoPanels.put(table, tableInfoPanel);
        }

        return infoPanels;
    }

    @Override
    public void refresh() {
        _tables.setModel(getTablesTreeModel());

        tableInfoPanels = createTableInfoPanels();
    }
}
